<template>
  <div class="ele-upload-image" :style="hideUploadFileIcon ? 'display: inherit' : ''">
    <!-- 图片列表 -->
    <div class="ele-multiple-gallery">
      <!-- <ele-gallery
        :lazy="lazy"
        :remove-fn="handleRemove"
        :size="size"
        :sliceSingle="true"
        :source="computedValues"
        :thumbSuffix="thumbSuffix"
        :title="title"
        :carousel-attrs="carouselAttrs"
      /> -->

      <ul class="el-upload-list el-upload-list--picture-card">
        <draggable v-model="computedValues">
          <transition-group name="fade">
            <li
              v-for="(item, index) in computedValues"
              :key="item"
              class="el-upload-list__item is-success animated"
            >
              <img :src="item" class="el-upload-list__item-thumbnail" />
              <i class="el-icon-close"></i>
              <span class="el-upload-list__item-actions">
                <!-- 预览 -->
                <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(item)">
                  <i class="el-icon-zoom-in"></i>
                </span>
                <!-- 删除 -->
                <span class="el-upload-list__item-delete" @click="handleRemove(index)">
                  <i class="el-icon-delete"></i>
                </span>
              </span>
            </li>
          </transition-group>
        </draggable>
      </ul>
    </div>

    <!-- 上传组件 -->
    <el-upload
      :accept="accept"
      :action="action"
      :data="ossKey"
      :disabled="disabled"
      :drag="Boolean(drag)"
      :headers="headers"
      :http-request="httpRequest"
      :limit="limit"
      :list-type="drag ? 'picture' : 'picture-card'"
      :multiple="multiple"
      :name="name"
      :on-change="handleChange"
      :before-upload="beforeUploadImage"
      :on-error="handleUploadError"
      :on-exceed="handleExceed"
      :file-list="fileList"
      :show-file-list="false"
      :withCredentials="withCredentials"
      :class="{ hideUploadFileIcon: hideUploadFileIcon }"
      ref="upload"
    >
      <div v-loading="uploading">
        <!-- drag显示 -->
        <template v-if="drag">
          <i class="el-icon-upload"></i>
          <div class="el-upload__text">
            将文件拖到此处，或
            <em>点击上传</em>
          </div>
        </template>

        <!-- 非drag -->
        <template v-else>
          <div
            :style="{
              width: size + 'px',
              height: size + 'px',
              lineHeight: size + 'px'
            }"
          >
            <i class="el-icon-plus"></i>
          </div>
        </template>
      </div>

      <!-- 公共 -->
      <div class="el-upload__tip" slot="tip" v-if="showTip">
        请上传
        <b style="color: #f56c6c">{{ fileType.length ? fileType.join('/') : '图片' }}</b>
        格式文件
        <template v-if="filePixel">
          ，尺寸为
          <b style="color: #f56c6c">{{ filePixel }}</b>
        </template>
        <template v-if="fileSize">
          ，且大小不超过
          <b style="color: #f56c6c">{{ fileSize }}MB</b>
        </template>
        <template v-if="multiple">
          ，限制上传
          <b style="color: #f56c6c">{{ limit }}张</b>
        </template>
      </div>
    </el-upload>

    <!-- 预览弹出层 -->
    <el-dialog :visible.sync="previewVisible">
      <img width="100%" :src="previewImageUrl" />
    </el-dialog>
  </div>
</template>

<script>
import axios from 'axios'
import { getOss } from '@/utils/alioss'
import { setUpFileName } from '@/hooks'
import draggable from 'vuedraggable'
// import EleGallery from 'vue-ele-gallery'
export default {
  name: 'UploadImage',
  components: {
    // EleGallery
    draggable
  },
  props: {
    // 值
    value: {
      type: [String, Array],
      default() {
        return []
      }
    },
    // 是否禁用
    disabled: {
      type: Boolean,
      default: false
    },
    // 图片显示大小
    size: {
      type: Number,
      default: 150
    },
    // 大小限制(MB)
    fileSize: {
      type: Number
    },
    // 图片尺寸
    filePixel: {
      type: String
    },
    // 文件类型, 例如['png', 'jpg', 'jpeg']
    fileType: {
      type: Array,
      default: () => []
    },
    // 是否显示上传成功的提示
    isShowSuccessTip: {
      type: Boolean,
      default: true
    },
    // 缩略图后缀, 例如七牛云缩略图样式 (?imageView2/1/w/20/h/20)
    thumbSuffix: {
      type: String,
      default: ''
    },
    // 是否显示提示
    isShowTip: {
      type: Boolean,
      default: true
    },
    // 弹窗标题
    title: String,
    // 图片懒加载
    lazy: {
      type: Boolean,
      default: false
    },
    // 设置上传的请求头部(同官网)
    headers: Object,
    // 文件个数显示(同官网)
    limit: {
      type: Number,
      default: 1
    },
    // 是否启用拖拽上传 (同官网)
    drag: {
      type: Boolean,
      default: false
    },
    // 	支持发送 cookie 凭证信息 (同官网)
    withCredentials: {
      type: Boolean,
      default: false
    },
    // 是否支持多选文件 (同官网)
    multiple: {
      type: Boolean,
      default: false
    },
    // 上传时附带的额外参数(同官网)
    data: Object,
    // 上传的文件字段名 (同官网)
    name: {
      type: String,
      default: 'file'
    },
    // 接受上传的文件类型（thumbnail-mode 模式下此参数无效）(同官网)
    accept: String,
    // 删除前的操作
    beforeRemove: Function,
    // 响应处理函数
    responseFn: Function,
    carouselAttrs: {
      type: Object,
      default: () => {
        return {
          interval: 4000,
          type: 'card',
          height: '200px'
        }
      }
    }
  },
  data() {
    return {
      action: '#',
      uploading: false,
      fileList: [],
      // oss相关参数
      ossKey: {
        key: '',
        bucketName: '',
        objPath: '',
        policy: '',
        signature: ''
      },
      showBack: true,
      // dialogImageUrl: '',
      // dialogVisible: false
      previewVisible: false,
      previewImageUrl: ''
    }
  },
  computed: {
    // 是否显示提示
    showTip() {
      return this.isShowTip && (this.fileType.length || this.fileSize)
    },
    computedValues: {
      get() {
        if (this.value) {
          if (typeof this.value === 'string') {
            return [this.value]
          } else {
            return [...this.value]
          }
        } else {
          return []
        }
      },
      set(value) {
        if (typeof value === 'string') {
          this.$emit('input', [value])
        } else {
          this.$emit('input', [...value])
        }
      }
    },
    hideUploadFileIcon() {
      if (this.multiple) {
        let imgList = typeof this.value === 'string' ? [this.value] : [...this.value]
        return imgList.length >= this.limit
      } else {
        return false
      }
    }
  },
  methods: {
    handleChange(file, fileList) {
      this.uploading = false
      this.fileList = fileList
      this.$emit('on-change')
    },
    // 文件个数超出
    handleExceed() {
      this.$message.error(`最多上传${this.limit}张图片`)
    },
    // 上传失败
    handleUploadError(err) {
      this.uploading = false
      this.$message.error('上传失败, 请重试')
      this.$emit('error', err)
    },
    // 上传之前校验格式
    beforeUploadImage(file) {
      let isImg = false
      if (this.fileType.length) {
        let fileExtension = ''
        if (file.name.lastIndexOf('.') > -1) {
          fileExtension = file.name.slice(file.name.lastIndexOf('.') + 1)
        }
        isImg = this.fileType.some(type => {
          if (file.type.indexOf(type) > -1) return true
          if (fileExtension && fileExtension.indexOf(type) > -1) return true
          return false
        })
      } else {
        isImg = file.type.indexOf('image') > -1
      }

      if (!isImg) {
        this.$message.error(`文件格式不正确, 请上传${this.fileType.join('/')}图片格式文件!`)
        return false
      }
      if (this.fileSize) {
        const isLt = file.size / 1024 / 1024 < this.fileSize
        if (!isLt) {
          this.$message.error(`上传头像图片大小不能超过 ${this.fileSize} MB!`)
          return false
        }
      }
    },
    async httpRequest({ file }) {
      // 得到文件的内容
      let fileArray = []
      fileArray.push(file)

      let uploadImage = async file => {
        //填写获取签名的地址
        const policyData = await getOss()
        let ossUrl = 'https://oss.wasaiyouxuan.com' //填写自己OSS服务器的地址
        let accessUrl = policyData.objPath + setUpFileName(file) //设置上传的访问路径
        let fromData = new FormData() // 上传文件的data参数

        // form提交
        fromData.append('OSSAccessKeyId', 'LTAI5tATQrBDh3vWLfLAxgHT')
        fromData.append('policy', policyData.policy)
        fromData.append('Signature', policyData.signature)
        fromData.append('bucketName', policyData.bucketName)
        fromData.append('key', accessUrl)
        fromData.append('objPath', policyData.objPath)
        fromData.append('success_action_status', 200)
        fromData.append('file', file)

        await axios.post(ossUrl, fromData)
        return `${ossUrl}/${accessUrl}`
      }

      // 循环上传
      fileArray.forEach(file => {
        uploadImage(file).then(data => {
          this.uploading = false
          if (this.isShowSuccessTip) {
            this.$message.success('上传成功')
          }
          if (this.multiple) {
            if (Array.isArray(this.value)) {
              this.$emit('input', [...this.value, data])
            } else {
              this.$emit('input', [data])
            }
          } else {
            this.$emit('input', data)
          }
        })
      })
    },

    // 删除图片
    handleRemove(index) {
      if (this.multiple) {
        const data = [...this.computedValues]
        data.splice(index, 1)
        this.fileList.splice(index, 1)
        this.$emit('input', data || [])
      } else {
        this.$emit('input', '')
        this.fileList = []
      }
    },

    // 预览图片
    handlePictureCardPreview(url) {
      this.previewImageUrl = url
      this.previewVisible = true
    }
  }
}
</script>

<style lang="scss" scoped>
.ele-upload-image {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  line-height: 1;
  margin-bottom: 20px;
  .el-loading-spinner {
    line-height: 1;
  }
  .el-icon-plus {
    vertical-align: middle;
  }
  .el-upload--picture-card {
    width: auto;
    height: auto;
    background: none;
    line-height: inherit;
  }
}

.el-upload__tip {
  position: absolute;
  left: 0;
  margin: 10px 0;
}

.hideUploadFileIcon {
  width: 100%;
  height: 100%;
  /deep/ .el-upload--picture-card {
    display: none;
  }
}
</style>
